package com.heroh.codegenerator.vo;

import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.heroh.db.DbConfig;
import com.heroh.util.CamelUtil;
import lombok.Data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 包名称： com.heroh.constant
 * 类名称：ConfigConst
 * 类描述：
 * 创建人：@author shengxiong.jian
 * 创建时间：2020/2/21/15:56
 */
@Data
public class ConfigConst {

    private DbConfig dbConfig;

    private ProjectVO projectVO;

    private String reqUrl;

    private String reqMethod;

    private String requestColumns;

    private String[] tables;

    public ConfigConst(Builder builder) {
        this.dbConfig = builder.dbConfig;
        this.projectVO = builder.projectVO;
        this.reqUrl = builder.reqUrl;
        this.reqMethod = builder.reqMethod;
        this.requestColumns = builder.requestColumns;
        this.tables = builder.tables;
    }

    public Map<String, Object> getCustomer() {
        Map<String, Object> params = new HashMap<>();
        params.put("project", projectVO.getProjectName());
        params.put("package", projectVO.getParentName());
        params.put("right", projectVO.getRight());
        params.put("copy", projectVO.getCopy());
        // 类型转换器
        params.put("typeConvert", projectVO.getTypeConvert());
        // 公共字段
        params.put("basic_columns", projectVO.getBaseColumns());
        // 请求路径
        params.put("request_path", reqUrl);
        // 需要生成的方法
        params.put("request_methods", reqMethod);
        // 请求参数列
        params.put("request_columns", requestColumns);
        return params;
    }

    /**
     * 全局配置
     *
     * @author jianshengxiong
     * @date 2019/7/1/9:41
     */
    public GlobalConfig getGlobal() {
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir(System.getProperty("user.dir") + "/" + projectVO.getProjectName());
        gc.setAuthor(projectVO.getAuthor());
        gc.setOpen(false);
        gc.setDateType(DateType.ONLY_DATE);

        gc.setFileOverride(true);
        // XML ResultMap
        gc.setBaseResultMap(true);
        // XML columList

        gc.setBaseColumnList(true);
        // 自定义文件命名，注意 %s 会自动填充表实体属性！
        gc.setMapperName("%sMapper");
        gc.setXmlName("%sMapper");
        gc.setActiveRecord(false);
        gc.setSwagger2(true);
        gc.setKotlin(false);
        return gc;
    }

    /**
     * 包配置
     *
     * @author jianshengxiong
     * @date 2019/7/1/9:41
     */
    public PackageConfig getPackage() {
        PackageConfig pc = new PackageConfig();
        pc.setParent(projectVO.getParentName());
        pc.setMapper("dao");
        pc.setXml("dao/xml");
        return pc;
    }

    /**
     * 自定义配置
     *
     * @author jianshengxiong
     * @date 2019/7/1/9:41
     */
    public InjectionConfig getInject() {
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                setMap(getCustomer());
            }
        };
        List<FileOutConfig> focList = new ArrayList<>();
        // 添加自定义配置文件
        String templatePath = System.getProperty("user.dir") + "/" + projectVO.getProjectName() + CamelUtil.packagePath(projectVO.getParentName());
        for (TemplateEnum e : TemplateEnum.values()) {
            focList.add(initFileOutConfig(templatePath, e));
        }
        cfg.setFileOutConfigList(focList);
        return cfg;
    }

    public static FileOutConfig initFileOutConfig(String templatePath, TemplateEnum e) {
        return new FileOutConfig(e.getTemplatePath()) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return templatePath + e.getOutPackage() + tableInfo.getEntityName() + e.getTypeName();
            }
        };
    }

    /**
     * 生成默认数据源
     *
     * @author jianshengxiong
     * @date 2019/7/1/9:41
     */
    public DataSourceConfig getDB() {
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDriverName(dbConfig.getDriver());
        dsc.setUrl(dbConfig.getUrl());
        dsc.setUsername(dbConfig.getUser());
        dsc.setPassword(dbConfig.getPassword());
        return dsc;
    }

    /**
     * 策略配置
     *
     * @author jianshengxiong
     * @date 2019/7/1/9:42
     */
    public StrategyConfig getStrategy(String[] tableNames) {
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setInclude(tableNames);
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setRestControllerStyle(true);
        strategy.setEntityLombokModel(true);
        strategy.setSuperEntityClass(projectVO.getBaseEntity());
        strategy.setSuperEntityColumns(projectVO.getBaseColumns());
        strategy.setSuperControllerClass(projectVO.getBaseController());
        strategy.setEntitySerialVersionUID(false);
        strategy.setEntityTableFieldAnnotationEnable(false);
        return strategy;
    }

    public static class Builder {
        private DbConfig dbConfig;

        private ProjectVO projectVO;

        private String reqUrl;

        private String reqMethod;

        private String requestColumns;

        private String[] tables;

        public ConfigConst build() {
            if(dbConfig == null) {
                throw new RuntimeException("数据库连接对象不能为空");
            }
            if(projectVO == null) {
                throw new RuntimeException("项目对象不能为空");
            }
            return new ConfigConst(this);
        }

        public Builder setDbConfig(DbConfig dbConfig) {
            this.dbConfig = dbConfig;
            return this;
        }

        public Builder setProjectVO(ProjectVO projectVO) {
            this.projectVO = projectVO;
            return this;
        }

        public Builder setReqUrl(String reqUrl) {
            this.reqUrl = reqUrl;
            return this;
        }

        public Builder setReqMethod(String reqMethod) {
            this.reqMethod = reqMethod;
            return this;
        }

        public Builder setRequestColumns(String requestColumns) {
            this.requestColumns = requestColumns;
            return this;
        }

        public Builder setTables(String[] tables) {
            this.tables = tables;
            return this;
        }
    }

}
